/*
 * jMole.java
 *
 * Created on 25. Juni 2007, 15:06
 */

package org.australia.ui;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Observable;
import java.util.Observer;
import java.util.TreeSet;
import java.util.concurrent.ExecutionException;
import javax.swing.JOptionPane;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.Timer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.australia.algorithm.Criterion;
import org.australia.algorithm.GA;
import org.australia.algorithm.Individual;
import org.australia.algorithm.Status;
import org.australia.config.Config;
import org.australia.problem.Problem;
import org.australia.problem.ProblemBoccia;
import org.australia.problem.ProblemHolmberg;
import org.australia.util.HolmbergOptimal;
import org.jdesktop.swingworker.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

/**
 *
 * @author  Daniel_h4x
 */
public class jMole extends javax.swing.JFrame {
    
    private GAExecutorTask task;
    private Logger logger = Logger.getRootLogger();
    
    private TimeSeries dynTimeSeries;
    private TimeSeriesCollection dynSeriesCollection;
    private JFreeChart dynChart;
    private RegularTimePeriod dynPeriod;
    
    private static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("dd:MM:yy' 'HH:mm:ss");
    private static DecimalFormat TWO_DIGIT = new DecimalFormat();
    
    private static boolean PROGRESSBAR_INDETERMINATE = Boolean.FALSE;
    
    
    //colors and messages for certain events during GA execution
    private static String OPT_HIT_MSG = "Optimum getroffen !!";
    private static Color OPT_HIT_COLOR = new Color(50, 205, 50);
    
    private static String VALID_MSG = "Zul\u00e4ssig!";
    private static Color VALID_CLR =new Color(50, 205, 50);
    
    private static String INVALID_MSG = "Unzul\u00e4ssig!";
    private static Color INVALID_CLR = Color.RED;
    
    private static String STATE_GA_CANCELED = "GA abgebrochen!";
    private static String STATE_GA_FINISHED = "GA abgeschlossen!";
    private static String STATE_GA_RUNNING = "GA l\u00e4uft...";
    private static String STATE_GA_FAILED_START_ATTEMPT = "Konnte GA nicht starten. Fehler: ";
    private static String STATE_GA_FAILED_START_ATTEMPT_NO_INSTANCE = "Konnte GA nicht starten. Fehler: " + 
            "Keine Probleminstanz gew\u00e4hlt!";
    
    private static String DIALOG_EXIT_QUESTION = "Sind Sie sicher, dass Sie jMole beenden wollen?"; 
    private static String DIALOG_EXIT_CONFRIRM_EXIT = "Bitte best\u00e4tigen!";

    
    //restore the def-bg-color for textfields (second run of ga needs to be clean)
    private static Color DEF_BG_COLOR;
    
    //default values for the settings panel
    private static final String DEF_INSTANCE = "P1";
    private static final String DEF_GREEDY = "50%";
    private static final int DEF_POPSIZE = 100;
    private static final int DEF_GENERATIONS = 3000;
    private static final int DEF_FEE = 200;
    private static final int DEF_NEWGENSIZE = 2;
    private static final Selection DEF_SELMETHOD = Selection.ROULETTE;
    private static final boolean DEF_GA_CRITERION_IS_GENERATIONS = Boolean.TRUE; 
    
    private static enum Selection{
        RANDOM,
        ROULETTE
    }
    
    
    /** Creates new form jMole */
    public jMole() {
        
        logger.addAppender(new ConsoleAppender(new PatternLayout()));
        initComponents();
        setDefaultValues();
        drawInitialChart();
        
        DEF_BG_COLOR = OptimField.getBackground();
        TWO_DIGIT.setMaximumFractionDigits(2);
        logger.info("Success! UI established");
    }
    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        buttonGroup2 = new javax.swing.ButtonGroup();
        TabbedPanel = new javax.swing.JPanel();
        MainTabPane = new javax.swing.JTabbedPane();
        GASettingPanel = new javax.swing.JPanel();
        BasicSettingPanel = new javax.swing.JPanel();
        StartpopLabel = new javax.swing.JLabel();
        GenSizeLabel = new javax.swing.JLabel();
        PopSizeField = new javax.swing.JTextField();
        GenSizeField = new javax.swing.JTextField();
        FeeLabel = new javax.swing.JLabel();
        FeeSpinner = new javax.swing.JSpinner();
        GreedyLabel = new javax.swing.JLabel();
        GreedySpinner = new javax.swing.JSpinner();
        ChosenProblemField = new javax.swing.JTextField();
        ProblemChooserButton = new javax.swing.JButton();
        jLabel17 = new javax.swing.JLabel();
        ExtendedSettingPanel = new javax.swing.JPanel();
        chosenGenRButton = new javax.swing.JRadioButton();
        totalTimeRButton = new javax.swing.JRadioButton();
        timeNoImproveRButton = new javax.swing.JRadioButton();
        genNoImproveRButton = new javax.swing.JRadioButton();
        totalTimeField = new javax.swing.JTextField();
        timeNoImproveField = new javax.swing.JTextField();
        genNoImproveField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        LaufzeitInfoPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        BestIndiGeneField = new javax.swing.JTextField();
        BestIndiWareHousesField = new javax.swing.JTextField();
        BestIndiFitnessField = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        GAProgressBar = new javax.swing.JProgressBar();
        jLabel4 = new javax.swing.JLabel();
        BestIndiDurationField = new javax.swing.JTextField();
        jLabel12 = new javax.swing.JLabel();
        BestIndiValidField = new javax.swing.JTextField();
        jLabel15 = new javax.swing.JLabel();
        BestIndiFeeField = new javax.swing.JTextField();
        rootChartPanel = new javax.swing.JPanel();
        OptimLabel = new javax.swing.JLabel();
        OptimField = new javax.swing.JTextField();
        SetDefaultsButton = new javax.swing.JButton();
        CancelGAButton = new javax.swing.JButton();
        StartGA = new javax.swing.JButton();
        SelPressurePanel2 = new javax.swing.JPanel();
        RandomSelect = new javax.swing.JRadioButton();
        RouletteSelect = new javax.swing.JRadioButton();
        jSeparator3 = new javax.swing.JSeparator();
        ParentSelLabel2 = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        ChildrenSpinner = new javax.swing.JSpinner();
        ResultViewPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        TopMenu1 = new javax.swing.JMenuBar();
        DateiMenuItem1 = new javax.swing.JMenu();
        ExportMenu1 = new javax.swing.JMenu();
        CSVMenuItem1 = new javax.swing.JMenuItem();
        ExcelMenuItem1 = new javax.swing.JMenuItem();
        SepVorClose1 = new javax.swing.JSeparator();
        QuitMenuItem1 = new javax.swing.JMenuItem();
        BearbeitenMenu1 = new javax.swing.JMenu();
        UndoMenuItem1 = new javax.swing.JMenuItem();
        RedoMenuItem1 = new javax.swing.JMenuItem();
        SepVorZurueck1 = new javax.swing.JSeparator();
        ZurueckSetzenMenuItem1 = new javax.swing.JMenuItem();
        HilfeMenu1 = new javax.swing.JMenu();
        AboutMenuItem1 = new javax.swing.JMenuItem();
        StatusLabel1 = new javax.swing.JLabel();
        StatusTextLabel = new javax.swing.JLabel();
        TopMenu = new javax.swing.JMenuBar();
        DateiMenuItem = new javax.swing.JMenu();
        ExportMenu = new javax.swing.JMenu();
        CSVMenuItem = new javax.swing.JMenuItem();
        ExcelMenuItem = new javax.swing.JMenuItem();
        SepVorClose = new javax.swing.JSeparator();
        QuitMenuItem = new javax.swing.JMenuItem();
        BearbeitenMenu = new javax.swing.JMenu();
        UndoMenuItem = new javax.swing.JMenuItem();
        RedoMenuItem = new javax.swing.JMenuItem();
        SepVorZurueck = new javax.swing.JSeparator();
        ZurueckSetzenMenuItem = new javax.swing.JMenuItem();
        HilfeMenu = new javax.swing.JMenu();
        AboutMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("jMole");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        BasicSettingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Allgemeine Einstellungen"));

        StartpopLabel.setText("Größe der Startpopulation");

        GenSizeLabel.setText("Anzahl der Generationen");

        PopSizeField.setText("100");

        GenSizeField.setText("100");

        FeeLabel.setText("Höhe der Strafkosten");

        FeeSpinner.setModel(new javax.swing.SpinnerNumberModel(10.5d, 0.1d, 1000.0d, 0.5d));

        GreedyLabel.setText("Chance auf \"Greedy\"-Start");

        GreedySpinner.setModel(new javax.swing.SpinnerListModel(new String[] {"0% ", "25%", "50%", "75%", "100%"}));

        ChosenProblemField.setEditable(false);

        ProblemChooserButton.setText("Probleminstanz auswählen");
        ProblemChooserButton.setToolTipText("Dialog zum Auswählen der Probleminstanz");
        ProblemChooserButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ProblemChooserButtonActionPerformed(evt);
            }
        });

        jLabel17.setText("Probleminstanz");

        org.jdesktop.layout.GroupLayout BasicSettingPanelLayout = new org.jdesktop.layout.GroupLayout(BasicSettingPanel);
        BasicSettingPanel.setLayout(BasicSettingPanelLayout);
        BasicSettingPanelLayout.setHorizontalGroup(
            BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(BasicSettingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(StartpopLabel)
                    .add(GenSizeLabel)
                    .add(jLabel17))
                .add(18, 18, 18)
                .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(GenSizeField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 73, Short.MAX_VALUE)
                    .add(PopSizeField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 73, Short.MAX_VALUE)
                    .add(ChosenProblemField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 73, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(34, 34, 34)
                .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(FeeLabel)
                    .add(BasicSettingPanelLayout.createSequentialGroup()
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(ProblemChooserButton)
                            .add(GreedyLabel))))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(GreedySpinner)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, FeeSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(100, 100, 100))
        );
        BasicSettingPanelLayout.setVerticalGroup(
            BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(BasicSettingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(BasicSettingPanelLayout.createSequentialGroup()
                        .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(StartpopLabel)
                            .add(PopSizeField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(GenSizeLabel)
                            .add(GenSizeField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(jLabel17)
                            .add(ChosenProblemField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(ProblemChooserButton)))
                    .add(BasicSettingPanelLayout.createSequentialGroup()
                        .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                            .add(BasicSettingPanelLayout.createSequentialGroup()
                                .add(FeeSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED))
                            .add(org.jdesktop.layout.GroupLayout.TRAILING, BasicSettingPanelLayout.createSequentialGroup()
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .add(FeeLabel)
                                .add(9, 9, 9)))
                        .add(BasicSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(BasicSettingPanelLayout.createSequentialGroup()
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(GreedyLabel))
                            .add(BasicSettingPanelLayout.createSequentialGroup()
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(GreedySpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        ExtendedSettingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Kriterium für GA-Abbruch"));

        buttonGroup2.add(chosenGenRButton);
        chosenGenRButton.setSelected(true);
        chosenGenRButton.setText("beenden nach gewählter Anzahl an Generationen");
        chosenGenRButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        chosenGenRButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        buttonGroup2.add(totalTimeRButton);
        totalTimeRButton.setText("beenden nach");
        totalTimeRButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        totalTimeRButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        buttonGroup2.add(timeNoImproveRButton);
        timeNoImproveRButton.setText("beenden nach");
        timeNoImproveRButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        timeNoImproveRButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        buttonGroup2.add(genNoImproveRButton);
        genNoImproveRButton.setText("beenden nach");
        genNoImproveRButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        genNoImproveRButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        jLabel7.setText("Minuten an Laufzeit");

        jLabel9.setText("Minuten Stagnation");

        jLabel20.setText("Generationen Stagnation");

        org.jdesktop.layout.GroupLayout ExtendedSettingPanelLayout = new org.jdesktop.layout.GroupLayout(ExtendedSettingPanel);
        ExtendedSettingPanel.setLayout(ExtendedSettingPanelLayout);
        ExtendedSettingPanelLayout.setHorizontalGroup(
            ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(ExtendedSettingPanelLayout.createSequentialGroup()
                .add(ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(chosenGenRButton)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, ExtendedSettingPanelLayout.createSequentialGroup()
                        .add(ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, ExtendedSettingPanelLayout.createSequentialGroup()
                                .add(genNoImproveRButton)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                                .add(genNoImproveField))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, ExtendedSettingPanelLayout.createSequentialGroup()
                                .add(timeNoImproveRButton)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                                .add(timeNoImproveField))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, ExtendedSettingPanelLayout.createSequentialGroup()
                                .add(totalTimeRButton)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                                .add(totalTimeField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 62, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                        .add(ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jLabel7)
                            .add(jLabel9)
                            .add(jLabel20))))
                .addContainerGap())
        );
        ExtendedSettingPanelLayout.setVerticalGroup(
            ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(ExtendedSettingPanelLayout.createSequentialGroup()
                .add(chosenGenRButton)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(totalTimeRButton)
                    .add(totalTimeField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel7))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(timeNoImproveRButton)
                    .add(timeNoImproveField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel9))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(ExtendedSettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(genNoImproveRButton)
                    .add(genNoImproveField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel20))
                .addContainerGap(14, Short.MAX_VALUE))
        );

        LaufzeitInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Laufzeit-Informationen"));

        jLabel1.setText("Bestes Individuum");

        jLabel2.setText("Anzahl Lager");

        jLabel3.setText("Fitness");

        BestIndiGeneField.setEditable(false);
        BestIndiGeneField.setToolTipText("Gene des besten Individuums");

        BestIndiWareHousesField.setEditable(false);
        BestIndiWareHousesField.setToolTipText("Anzahl der verwendeten Lager des besten Individuums.");

        BestIndiFitnessField.setEditable(false);
        BestIndiFitnessField.setToolTipText("Fitness des derzeit besten Individuums.");

        jLabel5.setText("Fortschritt");

        GAProgressBar.setToolTipText("Fortschritt des GA...");

        jLabel4.setText("Dauer");

        BestIndiDurationField.setEditable(false);
        BestIndiDurationField.setToolTipText("Bisherige Dauer des aktuellen Durchlaufs");

        jLabel12.setText("Zulässigkeit");

        BestIndiValidField.setEditable(false);
        BestIndiValidField.setToolTipText("Gültigkeit des besten Individuums.");

        jLabel15.setText("Strafkosten");

        BestIndiFeeField.setEditable(false);
        BestIndiFeeField.setToolTipText("Strafkosten des besten Individuums.");

        OptimLabel.setText("Optimum");

        OptimField.setEditable(false);
        OptimField.setToolTipText("Bisherige Dauer des aktuellen Durchlaufs");

        org.jdesktop.layout.GroupLayout LaufzeitInfoPanelLayout = new org.jdesktop.layout.GroupLayout(LaufzeitInfoPanel);
        LaufzeitInfoPanel.setLayout(LaufzeitInfoPanelLayout);
        LaufzeitInfoPanelLayout.setHorizontalGroup(
            LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                                .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(jLabel1)
                                    .add(jLabel2)
                                    .add(jLabel3))
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                                            .add(BestIndiWareHousesField)
                                            .add(BestIndiFitnessField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 68, Short.MAX_VALUE))
                                        .add(30, 30, 30)
                                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                            .add(jLabel12)
                                            .add(jLabel15))
                                        .add(18, 18, 18)
                                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                                            .add(BestIndiFeeField)
                                            .add(BestIndiValidField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE))
                                        .add(18, 18, 18)
                                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                            .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                                                .add(jLabel4)
                                                .add(18, 18, 18)
                                                .add(BestIndiDurationField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 76, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                            .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                                                .add(OptimLabel)
                                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                                .add(OptimField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 76, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                                    .add(GAProgressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 473, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .add(BestIndiGeneField)))
                            .add(jLabel5)))
                    .add(rootChartPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 576, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        LaufzeitInfoPanelLayout.setVerticalGroup(
            LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jLabel5)
                    .add(GAProgressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel1)
                    .add(BestIndiGeneField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(jLabel2)
                            .add(jLabel12)
                            .add(BestIndiWareHousesField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(jLabel3)
                            .add(jLabel15)
                            .add(BestIndiFitnessField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                    .add(LaufzeitInfoPanelLayout.createSequentialGroup()
                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(BestIndiValidField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(jLabel4)
                            .add(BestIndiDurationField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(LaufzeitInfoPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(BestIndiFeeField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(OptimLabel)
                            .add(OptimField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(rootChartPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 216, Short.MAX_VALUE)
                .addContainerGap())
        );

        SetDefaultsButton.setText("Standard wiederherstellen");
        SetDefaultsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SetDefaultsButtonActionPerformed(evt);
            }
        });

        CancelGAButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/australia/ui/img/stop16.png"))); // NOI18N
        CancelGAButton.setText("GA abbrechen");
        CancelGAButton.setEnabled(false);
        CancelGAButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CancelGAButtonActionPerformed(evt);
            }
        });

        StartGA.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/australia/ui/img/forward16.png"))); // NOI18N
        StartGA.setText("GA starten");
        StartGA.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                StartGAActionPerformed(evt);
            }
        });

        SelPressurePanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Selektionsdruck"));

        buttonGroup1.add(RandomSelect);
        RandomSelect.setSelected(true);
        RandomSelect.setText("Zufall");
        RandomSelect.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        RandomSelect.setMargin(new java.awt.Insets(0, 0, 0, 0));

        buttonGroup1.add(RouletteSelect);
        RouletteSelect.setText("Roulette");
        RouletteSelect.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        RouletteSelect.setMargin(new java.awt.Insets(0, 0, 0, 0));

        ParentSelLabel2.setText("Auswahl der Eltern:");

        jLabel18.setText("Verhältnis an Kindern");

        jLabel19.setText("zu den Eltern");

        ChildrenSpinner.setModel(new javax.swing.SpinnerNumberModel(2.0d, 1.0d, 5.0d, 1.0d));

        org.jdesktop.layout.GroupLayout SelPressurePanel2Layout = new org.jdesktop.layout.GroupLayout(SelPressurePanel2);
        SelPressurePanel2.setLayout(SelPressurePanel2Layout);
        SelPressurePanel2Layout.setHorizontalGroup(
            SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(SelPressurePanel2Layout.createSequentialGroup()
                .addContainerGap(14, Short.MAX_VALUE)
                .add(SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(SelPressurePanel2Layout.createSequentialGroup()
                        .add(ParentSelLabel2)
                        .add(55, 55, 55)
                        .add(SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(RouletteSelect)
                            .add(RandomSelect)))
                    .add(SelPressurePanel2Layout.createSequentialGroup()
                        .add(SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(SelPressurePanel2Layout.createSequentialGroup()
                                .add(38, 38, 38)
                                .add(jLabel19))
                            .add(jLabel18))
                        .add(50, 50, 50)
                        .add(ChildrenSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 46, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .add(29, 29, 29))
            .add(jSeparator3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 251, Short.MAX_VALUE)
        );
        SelPressurePanel2Layout.setVerticalGroup(
            SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(SelPressurePanel2Layout.createSequentialGroup()
                .add(SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(SelPressurePanel2Layout.createSequentialGroup()
                        .add(RouletteSelect)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(RandomSelect))
                    .add(SelPressurePanel2Layout.createSequentialGroup()
                        .addContainerGap()
                        .add(ParentSelLabel2)))
                .add(20, 20, 20)
                .add(jSeparator3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 8, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(SelPressurePanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(SelPressurePanel2Layout.createSequentialGroup()
                        .add(jLabel18)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jLabel19))
                    .add(SelPressurePanel2Layout.createSequentialGroup()
                        .add(5, 5, 5)
                        .add(ChildrenSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        org.jdesktop.layout.GroupLayout GASettingPanelLayout = new org.jdesktop.layout.GroupLayout(GASettingPanel);
        GASettingPanel.setLayout(GASettingPanelLayout);
        GASettingPanelLayout.setHorizontalGroup(
            GASettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(GASettingPanelLayout.createSequentialGroup()
                .add(GASettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(GASettingPanelLayout.createSequentialGroup()
                        .add(5, 5, 5)
                        .add(BasicSettingPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, GASettingPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(SetDefaultsButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(CancelGAButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(StartGA, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(4, 4, 4))
                    .add(GASettingPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(GASettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, GASettingPanelLayout.createSequentialGroup()
                                .add(ExtendedSettingPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 321, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(SelPressurePanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .add(org.jdesktop.layout.GroupLayout.LEADING, LaufzeitInfoPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 594, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );
        GASettingPanelLayout.setVerticalGroup(
            GASettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(GASettingPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(BasicSettingPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 118, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(GASettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(SelPressurePanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE)
                    .add(ExtendedSettingPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(LaufzeitInfoPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(GASettingPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(SetDefaultsButton)
                    .add(CancelGAButton)
                    .add(StartGA))
                .addContainerGap())
        );

        GASettingPanelLayout.linkSize(new java.awt.Component[] {CancelGAButton, SetDefaultsButton}, org.jdesktop.layout.GroupLayout.VERTICAL);

        MainTabPane.addTab("Genetischer Algorithmus", GASettingPanel);

        jTable1.setModel(drawInitialTable());
        jScrollPane1.setViewportView(jTable1);

        org.jdesktop.layout.GroupLayout ResultViewPanelLayout = new org.jdesktop.layout.GroupLayout(ResultViewPanel);
        ResultViewPanel.setLayout(ResultViewPanelLayout);
        ResultViewPanelLayout.setHorizontalGroup(
            ResultViewPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(ResultViewPanelLayout.createSequentialGroup()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE)
                .addContainerGap())
        );
        ResultViewPanelLayout.setVerticalGroup(
            ResultViewPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(ResultViewPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 672, Short.MAX_VALUE)
                .addContainerGap())
        );

        MainTabPane.addTab("Resultat", ResultViewPanel);

        org.jdesktop.layout.GroupLayout TabbedPanelLayout = new org.jdesktop.layout.GroupLayout(TabbedPanel);
        TabbedPanel.setLayout(TabbedPanelLayout);
        TabbedPanelLayout.setHorizontalGroup(
            TabbedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(MainTabPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 619, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        );
        TabbedPanelLayout.setVerticalGroup(
            TabbedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(MainTabPane, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 722, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        );

        DateiMenuItem1.setMnemonic('D');
        DateiMenuItem1.setText("Datei");

        ExportMenu1.setText("Exportieren");

        CSVMenuItem1.setText("Komma-getrennte Datei");
        ExportMenu1.add(CSVMenuItem1);

        ExcelMenuItem1.setText("Excel Spreadsheet");
        ExportMenu1.add(ExcelMenuItem1);

        DateiMenuItem1.add(ExportMenu1);
        DateiMenuItem1.add(SepVorClose1);

        QuitMenuItem1.setText("jMole beenden");
        QuitMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                QuitMenuItemActionPerformed(evt);
            }
        });
        DateiMenuItem1.add(QuitMenuItem1);

        TopMenu1.add(DateiMenuItem1);

        BearbeitenMenu1.setText("Bearbeiten");

        UndoMenuItem1.setText("Rückgängig");
        BearbeitenMenu1.add(UndoMenuItem1);

        RedoMenuItem1.setText("Wiederherstellen");
        BearbeitenMenu1.add(RedoMenuItem1);
        BearbeitenMenu1.add(SepVorZurueck1);

        ZurueckSetzenMenuItem1.setText("Einstellungen für GA zurücksetzen");
        BearbeitenMenu1.add(ZurueckSetzenMenuItem1);

        TopMenu1.add(BearbeitenMenu1);

        HilfeMenu1.setText("Hilfe");

        AboutMenuItem1.setText("Über jMole");
        AboutMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AboutMenuItemActionPerformed(evt);
            }
        });
        HilfeMenu1.add(AboutMenuItem1);

        TopMenu1.add(HilfeMenu1);

        StatusLabel1.setText("Status:");

        StatusTextLabel.setText("Initialisiert");

        DateiMenuItem.setMnemonic('D');
        DateiMenuItem.setText("Datei");

        ExportMenu.setText("Exportieren");

        CSVMenuItem.setText("Komma-getrennte Datei");
        ExportMenu.add(CSVMenuItem);

        ExcelMenuItem.setText("Excel Spreadsheet");
        ExportMenu.add(ExcelMenuItem);

        DateiMenuItem.add(ExportMenu);
        DateiMenuItem.add(SepVorClose);

        QuitMenuItem.setText("jMole beenden");
        QuitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                QuitMenuItemActionPerformed(evt);
            }
        });
        DateiMenuItem.add(QuitMenuItem);

        TopMenu.add(DateiMenuItem);

        BearbeitenMenu.setText("Bearbeiten");

        UndoMenuItem.setText("Rückgängig");
        BearbeitenMenu.add(UndoMenuItem);

        RedoMenuItem.setText("Wiederherstellen");
        BearbeitenMenu.add(RedoMenuItem);
        BearbeitenMenu.add(SepVorZurueck);

        ZurueckSetzenMenuItem.setText("Einstellungen für GA zurücksetzen");
        BearbeitenMenu.add(ZurueckSetzenMenuItem);

        TopMenu.add(BearbeitenMenu);

        HilfeMenu.setText("Hilfe");

        AboutMenuItem.setText("Über jMole");
        AboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AboutMenuItemActionPerformed(evt);
            }
        });
        HilfeMenu.add(AboutMenuItem);

        TopMenu.add(HilfeMenu);

        setJMenuBar(TopMenu);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(TabbedPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .add(layout.createSequentialGroup()
                .add(2, 2, 2)
                .add(StatusLabel1)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(StatusTextLabel))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(TabbedPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(1, 1, 1)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(StatusLabel1)
                    .add(StatusTextLabel)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
    //listening for WindowClosing events and shutting down gracefully !   
    if (askForExit()) {
        this.dispose();
        System.exit(0);
    }
}//GEN-LAST:event_formWindowClosing
    
private void SetDefaultsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SetDefaultsButtonActionPerformed
    setDefaultValues();
}//GEN-LAST:event_SetDefaultsButtonActionPerformed

private void ProblemChooserButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ProblemChooserButtonActionPerformed
    new TreeProblemChooser(this, true, ChosenProblemField).setVisible(true);
}//GEN-LAST:event_ProblemChooserButtonActionPerformed

private void CancelGAButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CancelGAButtonActionPerformed
    task.stop();
    StartGA.setEnabled(true);
    SetDefaultsButton.setEnabled(true);
    CancelGAButton.setEnabled(false);
}//GEN-LAST:event_CancelGAButtonActionPerformed

private void StartGAActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StartGAActionPerformed
    
    // if we run the GA for the second time, the TimeSeries for the chart needs to be empty!
    dynTimeSeries.clear();
    
    //disable the defaults button
    SetDefaultsButton.setEnabled(false);
    
    //disable optimal-hit colorization
    
    BestIndiFitnessField.setBackground(DEF_BG_COLOR);
    OptimField.setBackground(DEF_BG_COLOR);
    

    // ALLGEMEINE EINSTELLUNGEN einlesen
    // get start pop size and amount of generations
    int startPopSize = Integer.parseInt(this.PopSizeField.getText());
    int generations = Integer.parseInt(this.GenSizeField.getText());
    
    // get chosen instance
    
    // get chosen instance
    String instance = ChosenProblemField.getText();

    // ERWEITERTE EINSTELLUNGEN einlesen
    // get greedy chance
    SpinnerModel greedyModel = this.GreedySpinner.getModel();
    double greedyChance = this.ConvertGreedyPercentage(greedyModel.getValue());

    // get amount of children to be reproduced
    SpinnerNumberModel childrenModel = (SpinnerNumberModel) this.ChildrenSpinner.getModel();
    double forcedChildren = childrenModel.getNumber().doubleValue();
    
    // get the value for fees
    SpinnerNumberModel feeModel = (SpinnerNumberModel) this.FeeSpinner.getModel();
    double fees = feeModel.getNumber().doubleValue();

    // get selection method
    boolean rouletteSelected = this.RouletteSelect.isSelected() ? true : false;
    int rouletteSelection = rouletteSelected ? 1 : 0;
    
        
    //GA ABBRUCHSKRITERIEN einlesen
    // default: chosen generations
    Criterion criterion = criterion = Criterion.GENERATIONS;
    int criterionValue = generations;
    
    if (chosenGenRButton.isSelected()) {
        criterion = Criterion.GENERATIONS;
        criterionValue = generations;
    }
    else if(totalTimeRButton.isSelected()) {
        criterion = Criterion.TOTALTIME;
        //transform minutes to seconds...
        criterionValue = Integer.parseInt(this.totalTimeField.getText()) * 60;
    }
    else if(timeNoImproveRButton.isSelected()) {
        criterion = Criterion.TIMENOIMPROVEMENTS;
        //transform minutes to seconds...
        criterionValue = Integer.parseInt(this.timeNoImproveField.getText()) * 60;
        
        // you cannot calculate a progressbar with this setting
        PROGRESSBAR_INDETERMINATE = true;
        
    }
    else if(genNoImproveRButton.isSelected()) {
        criterion = Criterion.GENERATIONSNOIMPROVEMENTS;
        criterionValue = Integer.parseInt(this.genNoImproveField.getText());
                
        // you cannot calculate a progressbar with this setting
        PROGRESSBAR_INDETERMINATE = true;
    }
    
    // log(abbruchskriterien);
    logger.debug("Criterion: "+ criterion.toString() + " value: " + criterionValue);
    
    // teilw. Input Werte in Config Klasse schreiben
    Config.setNewGenerationSize(forcedChildren);
    Config.setFee(fees);
    Config.setPercentageGreedy(greedyChance);
    Config.setSelectionMethod(rouletteSelection);
    
    try {
        
        Problem problem = null;
        
        // SwingWorker ab hier!
        if (instance.startsWith("P")) {
            problem = ProblemHolmberg.readProblem(instance);
            OptimField.setText(""+ HolmbergOptimal.getOptimal(problem));
        } else if (instance.startsWith("i")) {
            problem = ProblemBoccia.readProblem(instance);
            OptimField.setText("n/a");
        } else if (!instance.startsWith("P") & !instance.startsWith("i")) {
            StatusTextLabel.setText(STATE_GA_FAILED_START_ATTEMPT_NO_INSTANCE);
        }
        
        if (problem != null) {
            task = new GAExecutorTask(problem, startPopSize, criterion, criterionValue);
            
            
            GAProgressBar.setValue(0);
            GAProgressBar.setIndeterminate(PROGRESSBAR_INDETERMINATE);
            BestIndiDurationField.setText("");
            BestIndiFitnessField.setText("");
            BestIndiGeneField.setText("");
            BestIndiWareHousesField.setText("");
            StartGA.setEnabled(false);
            CancelGAButton.setEnabled(true);
            
            // here we go !
            task.execute();
        }
    } catch (Exception e) {
        
        StatusTextLabel.setText(STATE_GA_FAILED_START_ATTEMPT + e.getClass().getName());
        logger.fatal(e.getMessage(),e);
    }
}//GEN-LAST:event_StartGAActionPerformed

private boolean askForExit() {
    //view JOptionPane javadoc for explanation
    int n = JOptionPane.showOptionDialog(
            this,             
            DIALOG_EXIT_QUESTION,
            DIALOG_EXIT_CONFRIRM_EXIT,
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE,
            null, null, null);
    
    return n == JOptionPane.YES_OPTION;
}
private void QuitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_QuitMenuItemActionPerformed
    
    if (askForExit()) {
        this.dispose();
        System.exit(0);
    }
}//GEN-LAST:event_QuitMenuItemActionPerformed

    private void AboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AboutMenuItemActionPerformed
        new AboutDialog(this, false).setVisible(true);
}//GEN-LAST:event_AboutMenuItemActionPerformed
    
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
                    }//GEN-LAST:event_jMenuItem1ActionPerformed

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    try {
        javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
        java.awt.EventQueue.invokeLater(new java.lang.Runnable() {
            
            public void run() {
                jMole jm = new org.australia.ui.jMole();
                jm.setLocationByPlatform(true);
                jm.setVisible(true);
                
            }
        });
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

/**
 * Subclass of Swingworker to execute the GA asynchronously in a background thread (responsive UI)
 *
 *
 * */
class GAExecutorTask extends SwingWorker<Individual, Status>{
    
    Problem problem;
    GA ga;
    GAStateObserver gaso;
    DurationLabelListener durationListener;
    ChartUpdateListener chartupdater;
    
    Timer timer;
    
    int startPopSize;
    int value;
    Criterion criterion;
    boolean stoppedByUser = false;
    
    public GAExecutorTask(Problem problem, int startPopSize, Criterion criterion, int value){
        
        this.problem = problem;
        this.startPopSize = startPopSize;
        this.value = value;
        this.criterion = criterion;
        
        durationListener = new DurationLabelListener();
        chartupdater = new ChartUpdateListener(dynTimeSeries,dynPeriod);
        
        gaso = new GAStateObserver(this.value, chartupdater);
        ga = new GA(problem);
        ga.getStatus().addObserver(gaso);
        
    }
    
    protected Individual doInBackground() {
        
        Individual  bestfound = null;
        
        try {
            StatusTextLabel.setText(STATE_GA_RUNNING);
            
            logger.info("Starting GA as background task");
            
            // start the Timer to throw Actionevents to the chartupdater/DurationListener every 1000 ms
            
            timer = new Timer(1000, chartupdater);
            
            durationListener.aboutToStart();
            timer.addActionListener(durationListener);
            timer.start();
            
            
            // Finally start the GA
            bestfound = ga.startAlgorithm(startPopSize, criterion, value);
            
            logger.info("Finished GA as background task");
            
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        
        
        return bestfound;
    }
    
    @Override
    protected void done() {
                          
            timer.removeActionListener(chartupdater);
            timer.removeActionListener(durationListener);
            timer.stop();
            if (isCancelled() || stoppedByUser == true) {
                StatusTextLabel.setText(STATE_GA_CANCELED);
            } else {
                StatusTextLabel.setText(STATE_GA_FINISHED);
            }
            StartGA.setEnabled(true);
            CancelGAButton.setEnabled(false);
            SetDefaultsButton.setEnabled(true);
           
                //after we are done, we add the best indi to the table on the second tab
           try {   
                appendBestIndividual2Table(get(), new java.util.Date(), BestIndiDurationField.getText());
                
           } 
           catch (InterruptedException ex) {logger.fatal(ex.getMessage(),ex); } 
           catch (ExecutionException ex) { logger.fatal(ex.getMessage(),ex);  }
            
           GAProgressBar.setIndeterminate(false); 
    }
    
    public void stop(){
        
        try{
            this.ga.setStopped(true);
            stoppedByUser = true;
        }catch(Exception e){
            logger.fatal("Attempt to stop GA failed for reason: \n", e);
            e.printStackTrace();
        }
        
    }
    
}

/**
 * Observes the GA and receives updates from it in order to update the UI (delegation)
 *
 *
 * */
class GAStateObserver implements Observer{
    
    private ChartUpdateListener cul;
    private int generations;
    
    public GAStateObserver(int generations, ChartUpdateListener cul){
        
        this.generations = generations;
        this.cul = cul;
        
    }
    
    //update UI
    public void update(Observable o, Object arg) {
        
        Status stat = (Status) o;
        
        try{
            java.awt.EventQueue.invokeAndWait( new GAProgressRunnable(stat, generations, cul));
        } catch(Exception e){
            e.printStackTrace();
            
        }
    }
}

/**
 * Runnable that encapsulates the UI-update logic
 *
 * will be put on the EventDispatchThread by the GAStateObserver.
 *
 * */
class GAProgressRunnable implements Runnable{
    
    
    private Status stat;
    private int generations;
    
    private ChartUpdateListener cul;
    
    public GAProgressRunnable(Status stat, int generations, ChartUpdateListener cul) {
        this.stat = stat;
        this.generations = generations;
        this.cul = cul;
    }
    
    public void run() {
        
        int iteration = stat.getCurrentGeneration();
        Individual bestIndi = stat.getCurrentBestIndividual();
        
        // update UI according to these values
        
        //progressbar
        
        int progress = (int)((iteration / (double)generations) * 100);
        GAProgressBar.setValue(progress);
               
        // update the runtime-info field for the best individual
        
        if(bestIndi != null){
            
            String geneString = bestIndi.getGeneString();
            
            if(!geneString.equals(BestIndiGeneField.getText())){
                BestIndiGeneField.setText(geneString);
            }
            
            double fitness = bestIndi.getFitness();
            cul.setFitness(fitness);
            
            if (bestIndi.getProblem() instanceof ProblemHolmberg) {
                if(HolmbergOptimal.isOptimal(bestIndi) && !StatusTextLabel.getText().contains(OPT_HIT_MSG)){
                    StatusTextLabel.setText(StatusTextLabel.getText() + OPT_HIT_MSG );
                    BestIndiFitnessField.setBackground(OPT_HIT_COLOR);
                    OptimField.setBackground(OPT_HIT_COLOR);
                }
            }
            
            
            
            BestIndiFitnessField.setText(TWO_DIGIT.format(fitness));
            BestIndiFeeField.setText("" + bestIndi.getFeeCosts());
            
            if(bestIndi.isValid()){
                BestIndiValidField.setText(VALID_MSG);
                BestIndiValidField.setForeground(VALID_CLR);
            } else {
                BestIndiValidField.setText(INVALID_MSG);
                BestIndiValidField.setForeground(INVALID_CLR);
            }
            
            // add all genes to a set to remove duplicates -> amount of warehouse == size of set
            int[] genes = bestIndi.getGene();
            TreeSet<Integer> set = new TreeSet<Integer>();
            
            for (int i = 0; i < genes.length; i++) {
                set.add(genes[i]);
            }
            
            BestIndiWareHousesField.setText("" + set.size());
            
        }
        
    }
    
}


/**
 * Listener to update the durationLabel. Gets called by a Swing Timer every 1000 ms to asure the correct time.
 *
 *
 * */
class DurationLabelListener implements ActionListener{
    
    private Date start = null;
    SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
    
    public void aboutToStart() {
        
        if(start == null){
            this.start = new Date();
        }
        
    }
    
    public void actionPerformed(ActionEvent e) {
        
        if(start == null){
            throw new RuntimeException("A Timer-Event was created, but aboutToStart() has not been called.");
        }
        
        long ms = new Date().getTime() -  start.getTime();
        BestIndiDurationField.setText(sdf.format(new Date(ms)));
        
    }
}

/**
 * Updates the chart curve every 1000 ms to the value of its property fitness. Accuracy using Swing.Timer
 *
 *
 * */
class ChartUpdateListener implements ActionListener{
    
    private double fitness = 0;
    private TimeSeries series = null;
    private RegularTimePeriod period = null;
    
    public ChartUpdateListener(TimeSeries series, RegularTimePeriod period) {
        
        this.series = series;
        this.period = period;
    }
    
    public double getFitness() {
        return fitness;
    }
    
    public void setFitness(double fitness) {
        this.fitness = fitness;
    }
    
    public void actionPerformed(ActionEvent evt) {
        
        period = period.next();
        series.add(period, fitness);
        
    }
    
}

private void drawInitialChart(){
    
    logger.info("Trying to draw initial chart");
    
    dynPeriod = new Second();
    dynTimeSeries = new TimeSeries("Verlauf der Fitness", Second.class);
    dynSeriesCollection = new TimeSeriesCollection(dynTimeSeries);
    
    dynChart = ChartFactory.createTimeSeriesChart(
            "",                              // title
            "Zeit",                         // time axis label (x)
            "Fitness",                      // value axis label (y)
            dynSeriesCollection,            // the timeseriescollection
            false,                          // legend
            true,                           // tooltips
            false);                         // urls
    
    XYPlot plot = dynChart.getXYPlot();
    ValueAxis axis = plot.getDomainAxis();
    axis.setAutoRange(true);
    
    // sets the x-axis on a fixed size/range
    //axis.setFixedAutoRange(60000.0);  // 60 seconds
    
    axis = plot.getRangeAxis();
    //axis.setRange(0.0, 100.0);
    
    
    plot.setBackgroundPaint(Color.lightGray);
    plot.setDomainGridlinePaint(Color.white);
    plot.setRangeGridlinePaint(Color.white);
    
    //draw a line on y-axis across the graph
    //draw the line only on actual data points
    plot.setRangeCrosshairVisible(true);
    plot.setRangeCrosshairLockedOnData(true);
    
    
    XYLineAndShapeRenderer r = (XYLineAndShapeRenderer) plot.getRenderer();
    r.setUseFillPaint(true);
    r.setBaseFillPaint(Color.white);
    
    int w = rootChartPanel.getWidth();
    int h = rootChartPanel.getHeight();
    
    ChartPanel chartPanel = new ChartPanel(dynChart,w,h,w,h,w,h,true,false,false,false,true,true);
    
    rootChartPanel.add(chartPanel);
    
    logger.info("  Success! Added initial chart to UI");
    
}


private void setDefaultValues(){
    
    this.PopSizeField.setText(""+ jMole.DEF_POPSIZE);
    this.GenSizeField.setText(""+ jMole.DEF_GENERATIONS);
    this.FeeSpinner.setValue(jMole.DEF_FEE);
    this.ChosenProblemField.setText(""+jMole.DEF_INSTANCE);
    
    this.GreedySpinner.getModel().setValue((Object)jMole.DEF_GREEDY);
    this.ChildrenSpinner.getModel().setValue(jMole.DEF_NEWGENSIZE);
    
    
    this.RouletteSelect.setSelected(jMole.DEF_SELMETHOD.equals(Selection.ROULETTE));
    this.chosenGenRButton.setSelected(DEF_GA_CRITERION_IS_GENERATIONS);
    
    
}

private TableModel drawInitialTable(){
    
    logger.info("Trying to draw initial table");
    
    TableModel t =  new DefaultTableModel
     // constructor parameters
     ( new Object [][] {},
       new String []{"ID", "Datum", "Probleminstanz", "Fitness", "Lager", "Zul\u00e4ssig", "Strafkosten", "Dauer"}
     )
     //anonymous class starting from here
    {
        Class[] types = new Class [] {
            Integer.class, String.class, String.class, String.class, Integer.class, Boolean.class, Double.class, String.class
        };
        boolean[] canEdit = new boolean [] {
            false, false, false, false, false, false, false, false
        };
        
            @Override
        public Class getColumnClass(int columnIndex) {
            return types [columnIndex];
        }
        
            @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return canEdit [columnIndex];
        }
    };
    
    logger.info("  Success! Added initial table to UI");
    
    return t;
}

private void appendBestIndividual2Table(Individual indi, Date date, String duration){
    
    int lastRow = jTable1.getModel().getRowCount();
  
    DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
    
    Object[] data = {lastRow+1,                             // ID
                     DAY_FORMAT.format(date),               // Date
                     indi.getProblem().getInstanceName(),   // instance
                     TWO_DIGIT.format(indi.getFitness()),   // fitness
                     indi.getFacilities().size(),           // warehouses
                     indi.isValid(),                        // valid?
                     indi.getFeeCosts(),                    // fees 
                     duration                               // GA run duration
                    };
    
    model.addRow(data);
}


/**
 * 
 * it feels so wrong... at least it works
 *
 */
private double ConvertGreedyPercentage(Object spinnerValue){
    
    String inputPercentage = (String)spinnerValue;
    double actualPercentage = -1;
    
    if(inputPercentage.startsWith("0")){
        actualPercentage = 0.0;
    } else if(inputPercentage.startsWith("25")){
        actualPercentage = 0.25;
    } else if(inputPercentage.startsWith("50")){
        actualPercentage = 0.5;
    } else if(inputPercentage.startsWith("75")){
        actualPercentage = 0.75;
    } else if(inputPercentage.startsWith("100"))
        actualPercentage = 1.0;
    
    return actualPercentage;
}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem AboutMenuItem;
    private javax.swing.JMenuItem AboutMenuItem1;
    private javax.swing.JPanel BasicSettingPanel;
    private javax.swing.JMenu BearbeitenMenu;
    private javax.swing.JMenu BearbeitenMenu1;
    private javax.swing.JTextField BestIndiDurationField;
    private javax.swing.JTextField BestIndiFeeField;
    private javax.swing.JTextField BestIndiFitnessField;
    private javax.swing.JTextField BestIndiGeneField;
    private javax.swing.JTextField BestIndiValidField;
    private javax.swing.JTextField BestIndiWareHousesField;
    private javax.swing.JMenuItem CSVMenuItem;
    private javax.swing.JMenuItem CSVMenuItem1;
    private javax.swing.JButton CancelGAButton;
    private javax.swing.JSpinner ChildrenSpinner;
    private javax.swing.JTextField ChosenProblemField;
    private javax.swing.JMenu DateiMenuItem;
    private javax.swing.JMenu DateiMenuItem1;
    private javax.swing.JMenuItem ExcelMenuItem;
    private javax.swing.JMenuItem ExcelMenuItem1;
    private javax.swing.JMenu ExportMenu;
    private javax.swing.JMenu ExportMenu1;
    private javax.swing.JPanel ExtendedSettingPanel;
    private javax.swing.JLabel FeeLabel;
    private javax.swing.JSpinner FeeSpinner;
    private javax.swing.JProgressBar GAProgressBar;
    private javax.swing.JPanel GASettingPanel;
    private javax.swing.JTextField GenSizeField;
    private javax.swing.JLabel GenSizeLabel;
    private javax.swing.JLabel GreedyLabel;
    private javax.swing.JSpinner GreedySpinner;
    private javax.swing.JMenu HilfeMenu;
    private javax.swing.JMenu HilfeMenu1;
    private javax.swing.JPanel LaufzeitInfoPanel;
    private javax.swing.JTabbedPane MainTabPane;
    private javax.swing.JTextField OptimField;
    private javax.swing.JLabel OptimLabel;
    private javax.swing.JLabel ParentSelLabel2;
    private javax.swing.JTextField PopSizeField;
    private javax.swing.JButton ProblemChooserButton;
    private javax.swing.JMenuItem QuitMenuItem;
    private javax.swing.JMenuItem QuitMenuItem1;
    private javax.swing.JRadioButton RandomSelect;
    private javax.swing.JMenuItem RedoMenuItem;
    private javax.swing.JMenuItem RedoMenuItem1;
    private javax.swing.JPanel ResultViewPanel;
    private javax.swing.JRadioButton RouletteSelect;
    private javax.swing.JPanel SelPressurePanel2;
    private javax.swing.JSeparator SepVorClose;
    private javax.swing.JSeparator SepVorClose1;
    private javax.swing.JSeparator SepVorZurueck;
    private javax.swing.JSeparator SepVorZurueck1;
    private javax.swing.JButton SetDefaultsButton;
    private javax.swing.JButton StartGA;
    private javax.swing.JLabel StartpopLabel;
    private javax.swing.JLabel StatusLabel1;
    private javax.swing.JLabel StatusTextLabel;
    private javax.swing.JPanel TabbedPanel;
    private javax.swing.JMenuBar TopMenu;
    private javax.swing.JMenuBar TopMenu1;
    private javax.swing.JMenuItem UndoMenuItem;
    private javax.swing.JMenuItem UndoMenuItem1;
    private javax.swing.JMenuItem ZurueckSetzenMenuItem;
    private javax.swing.JMenuItem ZurueckSetzenMenuItem1;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.ButtonGroup buttonGroup2;
    private javax.swing.JRadioButton chosenGenRButton;
    private javax.swing.JTextField genNoImproveField;
    private javax.swing.JRadioButton genNoImproveRButton;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JTable jTable1;
    private javax.swing.JPanel rootChartPanel;
    private javax.swing.JTextField timeNoImproveField;
    private javax.swing.JRadioButton timeNoImproveRButton;
    private javax.swing.JTextField totalTimeField;
    private javax.swing.JRadioButton totalTimeRButton;
    // End of variables declaration//GEN-END:variables
    
}
